<?php
/**
*
* @package MoltX QuickChat Cache Core
* @author $Author: moltendorf $
* @version $Id: molten_chat_cache.php 144 2009-09-20 04:28:22Z moltendorf $
* @latest $URL: https://molten-chat.googlecode.com/svn/trunk/source/includes/molten_chat/molten_chat_cache.php $
* @copyright (c) 2005-2009 Matthew Oltendorf
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/

// PHP: Hypertext Preprocessor Document

/*
	Unfinished Items:
		1.
		2.
		3.
		4.
		5.
*/

/*
	Known Issues:
		1.
		2.
		3.
		4.
		5.
*/

/**
* @ignore
*/
if (
	!defined ('molten_chat')
)
	{
		die ('Unauthorised Access.');
	}

// Style: Object Oriented.

/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
// Name: molten_chat_cache_core
// Type: Singleton.
// Title: MoltX Chat Cache Core Object.
// Description: Primary functions used by molten_chat_cache.
// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
class molten_chat_cache_core extends molten_chat_database
	{
		private static
			$_initialized,
			$directory,
			$lock,
			$room;

		/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
		// Name: __construct
		// Title: Class construction.
		// Variables: None.
		// Description: Disabled.
		// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
		private function __construct ()
			{
				// No further actions required.
				return false;
			}

		/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
		// Name: __destruct
		// Title: Class destruction.
		// Variables: None.
		// Description: Disabled.
		// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
		private function __destruct ()
			{
				// No further actions required.
				return false;
			}

		/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
		// Name: initialize
		// Title: Prepare object.
		// Variables: $variables
		//		1.	$variables: The array of references to molten_chat_server's internal variables.
		// Description: Load this object with required information.
		// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
		protected static function core_initialize (&$variables)
			{
				if (
					!self :: $_initialized and
					is_array ($variables)
				)
					{
						foreach ($variables as $variable => &$value)
							{
								if (
									!property_exists (__CLASS__, $variable)
								)
									{
										continue;
									}

								// Assign data to self.
								self :: $$variable = &$value;
							}
						unset ($value);

						self :: $_initialized = true;

						return true;
					}

				return false;
			}

		/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
		// Name: lock_memory
		// Title: Multi-instance locking.
		// Variables: $switch
		//	1.	$switch: Whether or not to lock out other threads.
		// Description: Prevents code from executing amongst other threads.
		// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
		protected static function lock_memory ($switch)
			{
				$lock = &self :: $lock ['memory'];

				$pointer = !empty ($lock ['pointer']) ?
					$lock ['pointer'] :
					($lock ['pointer'] = fopen (self :: $directory . 'memory.lock', 'a+'));

				if (
					$switch and
					!$lock ['switch']
				)
					{
						// Acquire lock without blocking.
						while (
							!flock ($pointer, LOCK_EX | LOCK_NB)
						)
							{
								// Generate a random number.
								$random = mt_rand (0, 250);

								// Sleep for 0.000 to 0.250 seconds. seconds.
								usleep (1000 * $random);
							}

						$lock ['switch'] = true;
					}
				elseif (
					!$switch and
					$lock ['switch']
				)
					{
						// Release lock.
						flock ($pointer, LOCK_UN);

						$lock ['switch'] = false;
					}
				else
					{
						return false;
					}

				return true;
			}

		/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
		// Name: lock_room
		// Title: Multi-instance locking.
		// Variables: $switch
		//	1.	$switch: Whether or not to lock out other threads.
		// Description: Prevents code from executing amongst other threads.
		// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
		protected static function lock_room ($switch)
			{
				$lock = &self :: $lock ['room'];

				$pointer = !empty ($lock ['pointer']) ?
					$lock ['pointer'] :
					($lock ['pointer'] = fopen (self :: $room ['files'] ['room'], 'a+'));

				if (
					$switch and
					!$lock ['switch']
				)
					{
						// Acquire lock without blocking.
						while (
							!flock ($pointer, LOCK_EX | LOCK_NB)
						)
							{
								// Generate a random number.
								$random = mt_rand (0, 250);

								// Sleep for 0.000 to 0.250 seconds. seconds.
								usleep (1000 * $random);
							}

						$lock ['switch'] = true;
					}
				elseif (
					!$switch and
					$lock ['switch']
				)
					{
						// Release lock.
						flock ($pointer, LOCK_UN);

						$lock ['switch'] = false;
					}
				else
					{
						return false;
					}

				return true;
			}

		/* --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- //
		// Name: lock_users
		// Title: Multi-instance locking.
		// Variables: $switch
		//	1.	$switch: Whether or not to lock out other threads.
		// Description: Prevents code from executing amongst other threads.
		// --|-- ----- ----- ----- -----|----- ----- ----- ----- --|-- */
		protected static function lock_users ($switch)
			{
				$lock = &self :: $lock ['users'];

				$pointer = !empty ($lock ['pointer']) ?
					$lock ['pointer'] :
					($lock ['pointer'] = fopen (self :: $room ['files'] ['users'], 'a+'));

				if (
					$switch and
					!$lock ['switch']
				)
					{
						// Acquire lock without blocking.
						while (
							!flock ($pointer, LOCK_EX | LOCK_NB)
						)
							{
								// Generate a random number.
								$random = mt_rand (0, 250);

								// Sleep for 0.000 to 0.250 seconds. seconds.
								usleep (1000 * $random);
							}

						$lock ['switch'] = true;
					}
				elseif (
					!$switch and
					$lock ['switch']
				)
					{
						// Release lock.
						flock ($pointer, LOCK_UN);

						$lock ['switch'] = false;
					}
				else
					{
						return false;
					}

				return true;
			}
	}